package AlgebraLinear.SistemaLinear;

//Essa classe foi só um teste para as funções de Equação Linear

public class EliminacaoGauss {
	
	public double[] Caucular(Double[][] equacao, double[] igualdade){
		
		//faço uma verificação para ver se eh uma matriz quadrada
		for(int i = 0; i< equacao.length; i++){
			if(equacao.length != equacao[i].length){
				throw new IllegalArgumentException("A Matriz informada não é quadrada");
			}
			//verifico se existe um campo nulo
			for(int j = 0; j < equacao[i].length; j++){
				if( equacao[i][j] == null ){
					throw new IllegalArgumentException("A Matriz informada possui valores nulos");
				}
			}
		}
		
		if(equacao.length != igualdade.length){
			throw new IllegalArgumentException("O Vetor de Resultados não é válido");
		}
		
		return Eliminacao(equacao, igualdade);
	}
	
	private double[] Eliminacao(Double[][] equacao, double[] igualdade){
		/**
			primeiro for para percorrer os estagios de eliminação
			uso equacao.length -1 , pois ele possui um estagio a menos do que linhas para haver solução
			*/
		for(int estagio = 0; estagio < (equacao.length - 1); estagio++){
			
			/**
			 * Um for para percorrer as linhas consequentes
			 */
			for(int i = (estagio + 1); i < equacao.length; i++){
			/**calculo o multiplicador, que deve ser:
			 *-1 * a divisao entre coeficiente da equação seguinte com 
			 *o coeficiente da equação do estagio
			*/
				
				double multiplicador = (equacao[i][estagio]/equacao[estagio][estagio])*-1;
				//aplico o valor 0 a linha onde a variavel foi eliminada
				equacao[i][estagio] = 0.0;
				//um novo for para prencher o resto da nova equação obtida
				for(int j=(estagio+1); j < equacao[i].length; j++){
					equacao[i][j] = equacao[i][j] + multiplicador * equacao[estagio][j];
				}
				
				//cauculo o novo resultado para o lado da igualdade
				igualdade[i] = igualdade[i] + multiplicador * igualdade[estagio];
			}
		}
		
		//convoco o metodo para obter os resuldados;
		return this.Resultados(equacao, igualdade);
	}
	
	private double[] Resultados(Double[][] novaMatriz, double igualdade[]){
		//crio um novo vetor para estanciar os resultados das variaveis
		double[] resultado = new double[novaMatriz.length];
		
		resultado[resultado.length-1] = igualdade[novaMatriz.length-1]/ novaMatriz[novaMatriz.length-1][novaMatriz.length-1];
		/**
		 * um for pra preencher o vetor com os resultados
		 * a variavel i percorrerá a matriz linha por linha de traz pra frente
		 * o i começa com novaMatriz/length - 2 para pular a referencia já definida acima
		*/
		for(int i = (novaMatriz.length-2); i >= 0; i--){
			//Cria uma variavel soma para instanciar os resultados dos coeficientes * o valor da variavel
			double soma = 0;
			//crio um for para percorrer as linhas
			//j recebe o valor de novaMatriz.length-1 para começar da ultima posição no caso
			for(int j = (i+1); j < novaMatriz.length ; j++){
				soma = soma + novaMatriz[i][j]*resultado[j];
			}
			//Calculo o resultado da variavel
			resultado[i] = ( igualdade[i] - soma )/novaMatriz[i][i];
		}
		
		//retorno o vetor de resultados
		return resultado;
	}
}
